#include "stdafx.h"
#include "BattleManager.h"

BattleManager::BattleManager()
{
	SetAutoDestroy(false);
	m_nTimerRemove = 0;
}
BattleManager::~BattleManager()
{

}
Battle* BattleManager::Add(BattleId id)
{
	Battle* pBattle = manager<Battle,BattleId>::Add(id);
	return pBattle;
}
bool BattleManager::Remove(BattleId id)
{
	return manager<Battle,BattleId>::Remove(id);
}

Battle* BattleManager::CreateByLUAId(Int32 nCharId,Int32 lua_id)
{
	BattleId nId = GenerateIdInt32();
	Battle* pBattle = Add(nId);
	if (pBattle == NULL) return NULL;
	LOGGER_INFO("CreateByLUAId:%p,lua_id:%d",this,lua_id);
	if(!pBattle->Startup(nCharId,lua_id))
	{
		Remove(nId);
		return NULL;
	}
	return pBattle;
}
void BattleManager::PrepareRemove(BattleId id)
{
	if(m_nTimerRemove == 0) 
		m_nTimerRemove = CreateTimer(boost::bind(&BattleManager::OnTimerRemove, this,_1),1000);
	m_listRemoved.push_back(id);
}
void BattleManager::OnTimerRemove(UInt32 nTimerId)
{	
	if(m_nTimerRemove != nTimerId)
	{
		LOGGER_ERROR("OnTimerRemove,m_nTimerRemove:%d,nTimerId:%d",m_nTimerRemove,nTimerId);
		DestroyTimer(nTimerId);
	}
	DestroyTimer(m_nTimerRemove);
	std::list<BattleId>::iterator iter = m_listRemoved.begin();
	std::list<BattleId>::iterator iterend = m_listRemoved.end();
	for (; iter != iterend; iter++)
	{
		Remove(*iter);
	}
	m_listRemoved.clear();
}

void BattleManager::EnterBattlePVE(PlayerId stPlayerId,Int32 lua_id,Int32 nBattleType)
{
	Player* pPlayer = singleton<PlayerManager>::instance().Get(stPlayerId);
	if (pPlayer == NULL)
	{
		LOGGER_ERROR("EnterBattle,pPlayer == NULL");
		return;
	}

	Battle* pBattle = CreateByLUAId(pPlayer->m_nCharId,lua_id);
	if (pBattle == NULL)
	{
		LOGGER_ERROR("EnterBattle,pBattle == NULL,lua_id:%d",lua_id);
		return;
	}
	Pet* pPet = NULL;
	Lover* pLover = NULL;
	pBattle->SetBattleType(nBattleType);
	if(pPlayer->isUseTeamSoul())
	{
		pBattle->AddPlayerAt(Battle::BATTLE_TEAM_0,0,pPlayer->GetPlayerId());
		pBattle->AddPartnerAt(Battle::BATTLE_TEAM_0,1,pPlayer->GetPlayerId());
		if(pPlayer->m_stCharInfo.m_nTeamSoulMemberSize < 0 || pPlayer->m_stCharInfo.m_nTeamSoulMemberSize > MAX_TEAM_SOUL_MEMBER_SIZE)
			pPlayer->m_stCharInfo.m_nTeamSoulMemberSize = 0;
		for (Int32 i = 0; i < pPlayer->m_stCharInfo.m_nTeamSoulMemberSize; i++)
		{
			pBattle->AddSoulAt(Battle::BATTLE_TEAM_0,(i+1)*2,pPlayer->m_stCharInfo.m_arTeamSoulMember[i]);
			pBattle->AddSoulAt(Battle::BATTLE_TEAM_0,(i+1)*2+1,pPlayer->m_stCharInfo.m_arTeamSoulMemberPartner[i]);
		}
	}
	else
	{
		if(pPlayer->isInTeam())
		{
			for (UInt32 i = 0; i < pPlayer->getTeamMemberSize(); i++)
			{
				Player* pMember = pPlayer->getTeamMemberByIndex(i);
				if (pMember == NULL)
				{
					pBattle->Clearup();
					LOGGER_ERROR("EnterBattle,pMember == NULL,lua_id:%d",lua_id);
					return;
				}
				pBattle->AddPlayerAt(Battle::BATTLE_TEAM_0,i*2,pMember->GetPlayerId());
				pBattle->AddPartnerAt(Battle::BATTLE_TEAM_0,i*2+1,pMember->GetPlayerId());
				//if(pMember->isTeamLeader())
					pMember->sendEnterMap();
			}
		}
		else
		{
			pBattle->AddPlayerAt(Battle::BATTLE_TEAM_0,0,pPlayer->GetPlayerId());
			pBattle->AddPartnerAt(Battle::BATTLE_TEAM_0,1,pPlayer->GetPlayerId());
			pPlayer->sendEnterMap();
		}
	}
	pBattle->SendEnterBattle();
	pBattle->RoundBegin();
}
Battle* BattleManager::EnterBattlePVPSoul(PlayerId stPlayerId,SoulCharInfo& stBattlerInfoChar,SoulCharInfo& stBattlerInfoPartner,Int32 nBattleType)
{
	Player* pPlayer = singleton<PlayerManager>::instance().Get(stPlayerId);
	if (pPlayer == NULL)
	{
		LOGGER_ERROR("EnterBattlePVP,pPlayer == NULL");
		return NULL;
	}

	//LOGGER_INFO("EnterBattlePVP:pPlayer0->IsInBattle():%d,pPlayer1->IsInBattle():%d",pPlayer0->IsInBattle(),pPlayer1->IsInBattle());
	BattleId nId = GenerateIdInt32();
	Battle* pBattle = Add(nId);
	if (pBattle == NULL) 
		return NULL;
	pBattle->SetBattleType(nBattleType);
	Lover* pLover = NULL;
	Pet* pPet = NULL;
	if(pPlayer->isUseTeamSoul())
	{
		pBattle->AddPlayerAt(Battle::BATTLE_TEAM_0,0,pPlayer->GetPlayerId());
		pBattle->AddPartnerAt(Battle::BATTLE_TEAM_0,1,pPlayer->GetPlayerId());
		if(pPlayer->m_stCharInfo.m_nTeamSoulMemberSize < 0 || pPlayer->m_stCharInfo.m_nTeamSoulMemberSize > MAX_TEAM_SOUL_MEMBER_SIZE)
			pPlayer->m_stCharInfo.m_nTeamSoulMemberSize = 0;
		for (Int32 i = 0; i < pPlayer->m_stCharInfo.m_nTeamSoulMemberSize; i++)
		{
			pBattle->AddSoulAt(Battle::BATTLE_TEAM_0,(i+1)*2,pPlayer->m_stCharInfo.m_arTeamSoulMember[i]);
			pBattle->AddSoulAt(Battle::BATTLE_TEAM_0,(i+1)*2+1,pPlayer->m_stCharInfo.m_arTeamSoulMemberPartner[i]);
		}
	}
	else
	{
		if(pPlayer->isInTeam())
		{
			for (UInt32 i = 0; i < pPlayer->getTeamMemberSize(); i++)
			{
				Player* pMember = pPlayer->getTeamMemberByIndex(i);
				if (pMember == NULL)
				{
					pBattle->Clearup();
					LOGGER_ERROR("EnterBattle,pMember == NULL");
					return  NULL;
				}
				pBattle->AddPlayerAt(Battle::BATTLE_TEAM_0,i*2,pMember->GetPlayerId());
				pBattle->AddPartnerAt(Battle::BATTLE_TEAM_0,i*2+1,pMember->GetPlayerId());
				//if(pMember->isTeamLeader())
					pMember->sendEnterMap();
			}
		}
		else
		{
			pBattle->AddPlayerAt(Battle::BATTLE_TEAM_0,0,pPlayer->GetPlayerId());
			pBattle->AddPartnerAt(Battle::BATTLE_TEAM_0,1,pPlayer->GetPlayerId());
			pPlayer->sendEnterMap();
		}
	}
	pBattle->AddSoul(Battle::BATTLE_TEAM_1,stBattlerInfoChar);
	pBattle->AddSoul(Battle::BATTLE_TEAM_1,stBattlerInfoPartner);
	pBattle->SendEnterBattle();
	pBattle->RoundBegin();
	return pBattle;
}
void BattleManager::EnterBattlePVP(PlayerId stPlayerId0,PlayerId stPlayerId1,Int32 nBattleType)
{
	Player* pPlayer0 = singleton<PlayerManager>::instance().Get(stPlayerId0);
	if (pPlayer0 == NULL)
	{
		LOGGER_ERROR("EnterBattlePVP,pPlayer0 == NULL");
		return;
	}

	Player* pPlayer1 = singleton<PlayerManager>::instance().Get(stPlayerId1);
	if (pPlayer1 == NULL)
	{
		LOGGER_ERROR("EnterBattlePVP,pPlayer1 == NULL");
		return;
	}

	if(!pPlayer0->addStamina(-1))
	{
		return;
	}
	//LOGGER_INFO("EnterBattlePVP:pPlayer0->IsInBattle():%d,pPlayer1->IsInBattle():%d",pPlayer0->IsInBattle(),pPlayer1->IsInBattle());
	BattleId nId = GenerateIdInt32();
	Battle* pBattle = Add(nId);
	if (pBattle == NULL) 
		return;
	pBattle->SetBattleType(nBattleType);
	Lover* pLover = NULL;
	Pet* pPet = NULL;
	Slave* pSlave = NULL;
	if(pPlayer0->isUseTeamSoul())
	{
		pBattle->AddPlayerAt(Battle::BATTLE_TEAM_0,0,pPlayer0->GetPlayerId());
		pBattle->AddPartnerAt(Battle::BATTLE_TEAM_0,1,pPlayer0->GetPlayerId());
		if(pPlayer0->m_stCharInfo.m_nTeamSoulMemberSize < 0 || pPlayer0->m_stCharInfo.m_nTeamSoulMemberSize > MAX_TEAM_SOUL_MEMBER_SIZE)
			pPlayer0->m_stCharInfo.m_nTeamSoulMemberSize = 0;
		for (Int32 i = 0; i < pPlayer0->m_stCharInfo.m_nTeamSoulMemberSize; i++)
		{
			pBattle->AddSoulAt(Battle::BATTLE_TEAM_0,(i+1)*2,pPlayer0->m_stCharInfo.m_arTeamSoulMember[i]);
			pBattle->AddSoulAt(Battle::BATTLE_TEAM_0,(i+1)*2+1,pPlayer0->m_stCharInfo.m_arTeamSoulMemberPartner[i]);
		}
	}
	else
	{
		if(pPlayer0->isInTeam())
		{
			for (UInt32 i = 0; i < pPlayer0->getTeamMemberSize(); i++)
			{
				Player* pMember = pPlayer0->getTeamMemberByIndex(i);
				if (pMember == NULL)
				{
					pBattle->Clearup();
					LOGGER_ERROR("EnterBattle,pMember == NULL");
					return;
				}
				pBattle->AddPlayerAt(Battle::BATTLE_TEAM_0,i*2,pMember->GetPlayerId());
				pBattle->AddPartnerAt(Battle::BATTLE_TEAM_0,i*2+1,pMember->GetPlayerId());
				//if(pMember->isTeamLeader())
					pMember->sendEnterMap();
			}
		}
		else
		{
			pBattle->AddPlayerAt(Battle::BATTLE_TEAM_0,0,pPlayer0->GetPlayerId());
			pBattle->AddPartnerAt(Battle::BATTLE_TEAM_0,1,pPlayer0->GetPlayerId());
			pPlayer0->sendEnterMap();
		}
	}
	//LOGGER_INFO("EnterBattlePVP1:pPlayer0->IsInBattle():%d,pPlayer1->IsInBattle():%d",pPlayer0->IsInBattle(),pPlayer1->IsInBattle());
	if(pPlayer1->isUseTeamSoul())
	{
		pBattle->AddPlayerAt(Battle::BATTLE_TEAM_1,0,pPlayer1->GetPlayerId());
		pBattle->AddPartnerAt(Battle::BATTLE_TEAM_1,1,pPlayer1->GetPlayerId());
		if(pPlayer1->m_stCharInfo.m_nTeamSoulMemberSize < 0 || pPlayer1->m_stCharInfo.m_nTeamSoulMemberSize > MAX_TEAM_SOUL_MEMBER_SIZE)
			pPlayer1->m_stCharInfo.m_nTeamSoulMemberSize = 0;
		for (Int32 i = 0; i < pPlayer1->m_stCharInfo.m_nTeamSoulMemberSize; i++)
		{
			pBattle->AddSoulAt(Battle::BATTLE_TEAM_1,(i+1)*2,pPlayer1->m_stCharInfo.m_arTeamSoulMember[i]);
			pBattle->AddSoulAt(Battle::BATTLE_TEAM_1,(i+1)*2+1,pPlayer1->m_stCharInfo.m_arTeamSoulMemberPartner[i]);
		}
	}
	else
	{
		if(pPlayer1->isInTeam())
		{
			for (UInt32 i = 0; i < pPlayer1->getTeamMemberSize(); i++)
			{
				Player* pMember = pPlayer1->getTeamMemberByIndex(i);
				if (pMember == NULL)
				{
					pBattle->Clearup();
					LOGGER_ERROR("EnterBattle,pMember == NULL");
					return;
				}
				pBattle->AddPlayerAt(Battle::BATTLE_TEAM_1,i*2,pMember->GetPlayerId());
				pBattle->AddPartnerAt(Battle::BATTLE_TEAM_1,i*2+1,pMember->GetPlayerId());
				//if(pMember->isTeamLeader())
					pMember->sendEnterMap();
			}
		}
		else
		{
			pBattle->AddPlayerAt(Battle::BATTLE_TEAM_1,0,pPlayer1->GetPlayerId());
			pBattle->AddPartnerAt(Battle::BATTLE_TEAM_1,1,pPlayer1->GetPlayerId());
			pPlayer1->sendEnterMap();
		}
	}

	pBattle->SendEnterBattle();
	pBattle->RoundBegin();
}

void BattleManager::LeaveBattle(Int32 nCharId)
{
	LOGGER_INFO("LeaveBattle,nCharId:%d",nCharId);
	Player* pPlayer = singleton<PlayerManager>::instance().GetByCharId(nCharId);
	if (pPlayer == NULL)
	{
		LOGGER_ERROR("LeaveBattle,pPlayer == NULL");
		return;
	}

	Battle* pBattle = Get(pPlayer->GetBattleId());
	if (pBattle == NULL)
	{
		LOGGER_ERROR("LeaveBattle,pBattle == NULL");
		return;
	}

	PacketEncoder encoder;
	encoder.AddItem(Int32(0));
	encoder.AddItem(Int32(301));
	encoder.AddItem(Int32(pPlayer->m_nCharId));
	pBattle->SendPacketToAll(encoder);

	pBattle->RemovePlayer(pPlayer->m_nCharId);
	pPlayer->sendEnterMap();
}